package sharemem

import (
	"server_cluster/common/gdconf"
	"server_cluster/common/logger"
	"server_cluster/common/protoc/pb"
	"sync/atomic"
)

const (
	// EQUIP_AFFIX_LIST_MAX = 5
	EQUIP_JEWEL_LIST_MAX = 3
	EQUIP_SKILL_LIST_MAX = 3
)

// type EquipAffix struct {
// 	AffixId     int32 // 词条id
// 	Level       int32 // 词条等级
// 	PropId      int32 // 属性id
// 	PropAddType int32 // 属性加成类型
// 	PropValue   int32 // 属性值
// }
//
// func (a *EquipAffix) Clear() {
// 	a.AffixId = 0
// 	a.Level = 0
// 	a.PropId = 0
// 	a.PropAddType = 0
// 	a.PropValue = 0
// }
//
// func (a *EquipAffix) Copy(equipAffix EquipAffix) {
// 	a.AffixId = equipAffix.AffixId
// 	a.Level = equipAffix.Level
// 	a.PropId = equipAffix.PropId
// 	a.PropAddType = equipAffix.PropAddType
// 	a.PropValue = equipAffix.PropValue
// }

type EquipSkill struct {
	SkillGroup int32 // 技能组
	Level      int32 // 等级
}

func (s *EquipSkill) IsUse() bool {
	return s.SkillGroup != 0
}

func (s *EquipSkill) MemInit() {
	s.SkillGroup = 0
	s.Level = 0
}

type Equip struct {
	Id         MyInt32 // 装备id
	Cell       int32   // 格子
	Level      int16   // 等级
	Exp        int32   // 经验
	LevelGroup int32   // 等级组
	// AffixList       [EQUIP_AFFIX_LIST_MAX]EquipAffix // 词条列表
	// AffixRemakeList [EQUIP_AFFIX_LIST_MAX]EquipAffix // 词条洗练列表
	RoleId    int32                            // 角色id
	JewelList [EQUIP_JEWEL_LIST_MAX]int32      // 宝石唯一key列表 注意 数组长度全部有效 0并不代表结束
	SkillList [EQUIP_SKILL_LIST_MAX]EquipSkill // 技能列表
}

func (e *Equip) MemInit() {
	e.Id.NewVal = 0
	e.Id.OldVal = 0
	e.Id.Status = 0
	e.Cell = 0
	e.Level = 0
	e.Exp = 0
	e.LevelGroup = 0
	e.RoleId = 0
	for i := 0; i < EQUIP_JEWEL_LIST_MAX; i++ {
		e.JewelList[i] = 0
	}
	for i := 0; i < EQUIP_SKILL_LIST_MAX; i++ {
		e.SkillList[i].MemInit()
	}
}

func (e *Equip) Clear() {
	e.Id.NewVal = 0
}

func (e *Equip) IsUse() bool {
	return e.Id.NewVal != 0 || e.Id.OldVal != 0
}

func (e *Equip) GetId() int32 {
	return e.Id.NewVal
}

func (e *Equip) SetSync() {
	atomic.AddUint32(&(e.Id.Status), 1)
}

func BuildEquipKey(id int32, cell int32) int32 {
	return id*1000 + cell
}

func ParseEquipKey(key int32) (id int32, cell int32) {
	return key / 1000, key % 1000
}

func (u *User) SetLastComposeEquip(equip *Equip) {
	index_game.UserMap[u.Id.NewVal].Equip.LastComposeEquip = equip
}
func (u *User) GetLastComposeEquip() *Equip {
	return index_game.UserMap[u.Id.NewVal].Equip.LastComposeEquip
}

func (u *User) RemoveEquip(equipKey, cell int32) {
	u.DeleteEquipMap(equipKey)
	u.Equip[cell].Clear()
}

func (e *Equip) GetMainProp() (mainPropId int32, mainPropAddType int8, mainPropValue int32) {
	equipLevelConfig := gdconf.GetConfigEquipLevelByGroupAndLevel(e.LevelGroup, int32(e.Level))
	if equipLevelConfig == nil {
		logger.Error("get equipLevelConfig is nil, levelGroup: %v, level: %v", e.LevelGroup, e.Level)
		return 0, 0, 0
	}
	fightPropAdd := equipLevelConfig.FightPropAdd
	if fightPropAdd == nil {
		return 0, 0, 0
	}
	mainPropId = fightPropAdd.PropId
	mainPropAddType = int8(fightPropAdd.AddType)
	mainPropValue = fightPropAdd.PropValue
	return mainPropId, mainPropAddType, mainPropValue
}

// // EquipAffixReplace 装备词条替换
// func (u *User) EquipAffixReplace(equip *Equip) {
// 	logger.Debug("equip affix replace, equipId: %v, uid: %v", equip.GetId(), u.GetUid())
// 	for i := 0; i < len(equip.AffixList); i++ {
// 		equip.AffixList[i].Clear()
// 	}
// 	for index, equipAffix := range equip.AffixRemakeList {
// 		if equipAffix.AffixId == 0 {
// 			break
// 		}
// 		equip.AffixList[index].Copy(equipAffix)
// 	}
// 	for i := 0; i < len(equip.AffixRemakeList); i++ {
// 		equip.AffixRemakeList[i].Clear()
// 	}
// 	equip.SetSync()
// 	logger.Debug("equip affix replace ok, equip: %v, uid: %v", equip, u.GetUid())
// }

// // EquipAffixRemake 装备词条洗练
// func (u *User) EquipAffixRemake(equip *Equip, req *pb.CS_EquipAffixRemakeReq) int16 {
// 	logger.Debug("equip affix remake, equipId: %v, uid: %v", equip.GetId(), u.GetUid())
// 	// 检查配置
// 	equipConfig := GetConfigEquip(equip.GetId())
// 	if equipConfig == nil {
// 		logger.Error("get equipConfig is nil, equipId: %v, uid: %v", equip.GetId(), u.GetUid())
// 		return config.CONFIG_NOT_FOUND
// 	}
// 	// 最高等级校验
// 	equipLevelConfig := GetConfigEquipLevelByGroupAndLevel(equip.LevelGroup, int32(equip.Level+1))
// 	if equipLevelConfig != nil {
// 		logger.Error("equip not arrive max level, equipId: %v, uid: %v", equip.GetId(), u.GetUid())
// 		return config.SERVER_ERROR
// 	}
// 	// 检查锁定词缀
// 	lockAffixIndexList := make([]int, 0)
// 	lockAffixLevelTotal := int32(0)
// 	for _, lockAffixId := range req.LockAffixIdList {
// 		exist := false
// 		for index, equipAffix := range equip.AffixList {
// 			if equipAffix.AffixId == 0 {
// 				break
// 			}
// 			if equipAffix.AffixId == lockAffixId {
// 				exist = true
// 				lockAffixIndexList = append(lockAffixIndexList, index)
// 				lockAffixLevelTotal += equipAffix.Level
// 				break
// 			}
// 		}
// 		if !exist {
// 			logger.Error("lock equip affix not found, equip: %v, lockAffixIdList: %v, uid: %v", equip, req.LockAffixIdList, u.GetUid())
// 			return config.OBJECT_NOT_FOUND
// 		}
// 	}
// 	// 校验并扣除道具
// 	for _, material := range equipConfig.SuccinctMaterialList {
// 		if !material.IsUse() {
// 			break
// 		}
// 		if !slices.ContainsFunc[[]*pb.Item_Req, *pb.Item_Req](req.ItemList, func(item *pb.Item_Req) bool {
// 			return item.Id == material.Id && item.Num == material.Num
// 		}) {
// 			logger.Error("client req item not match with config, uid: %v", u.GetUid())
// 			return config.SERVER_ERROR
// 		}
// 	}
// 	u.SubItems(req.ItemList)
// 	split := strings.Split(gdconf.GetConstStr("SUCCINCTCOST"), "|")
// 	if len(split) != 2 {
// 		return config.CONFIG_NOT_FOUND
// 	}
// 	itemId, err := strconv.Atoi(split[0])
// 	if err != nil {
// 		return config.CONFIG_NOT_FOUND
// 	}
// 	itemCount, err := strconv.Atoi(split[1])
// 	if err != nil {
// 		return config.CONFIG_NOT_FOUND
// 	}
// 	ok := u.CostItems(map[int32]int32{int32(itemId): int32(itemCount)})
// 	if !ok {
// 		return config.ITEM_NOT_ENOUGH
// 	}
// 	// 清空洗练列表
// 	for i := 0; i < len(equip.AffixRemakeList); i++ {
// 		equip.AffixRemakeList[i].Clear()
// 	}
// 	// 拷贝锁定词缀
// 	for _, index := range lockAffixIndexList {
// 		equip.AffixRemakeList[index].Copy(equip.AffixList[index])
// 	}
// 	// 追加洗练词条
// 	affixLevelTotal := int32(0)
// 	for _, equipAffix := range equip.AffixList {
// 		if equipAffix.AffixId == 0 {
// 			break
// 		}
// 		affixLevelTotal += equipAffix.Level
// 	}
// 	for i := 0; i < int(affixLevelTotal-lockAffixLevelTotal); i++ {
// 		ok := u.EquipAffixAppend(&(equip.AffixRemakeList), equipConfig, req.LockAffixIdList)
// 		if !ok {
// 			logger.Error("equip affix append fail, equipId: %v, uid: %v", equip.GetId(), u.GetUid())
// 		}
// 	}
// 	equip.SetSync()
// 	logger.Debug("equip affix remake ok, equip: %v, uid: %v", equip, u.GetUid())
// 	u.TriggerActivityTask(gdconf.ActivityTaskFinishCondEquipAffixRemake)
// 	return config.OK
// }

func (e *Equip) EquipSkillAppend(level int16) bool {
	logger.Debug("equip affix append, equipId: %v", e.GetId())
	for i := 0; i < len(e.SkillList); i++ {
		equipSkill := &(e.SkillList[i])
		if equipSkill.IsUse() {
			continue
		}
		equipConfig := gdconf.GetEquipConfig(e.GetId())
		if equipConfig == nil {
			return false
		}
		if level > equipConfig.MaxSkill2 {
			return true
		}
		list := make([]*gdconf.IdWeight, 0)
		for _, equipSkillGroupConfig := range gdconf.GetEquipSkillGroupConfigMap() {
			if equipSkillGroupConfig.SkillGroup != equipConfig.SkillGroup {
				continue
			}
			exist := false
			for _, equipSkill := range e.SkillList {
				if equipSkill.SkillGroup == 0 {
					break
				}
				if equipSkill.SkillGroup == equipSkillGroupConfig.Skill[0] {
					exist = true
					break
				}
			}
			if exist {
				continue
			}
			list = append(list, &gdconf.IdWeight{
				Id:     equipSkillGroupConfig.Id,
				Weight: equipSkillGroupConfig.Weight,
			})
		}
		skill := RWSRandom[*gdconf.IdWeight](list)
		if skill == nil {
			logger.Error("装备技能随机失败 %v", list)
			return false
		}
		equipSkillGroupConfig := gdconf.GetEquipSkillGroupConfig(skill.Id)
		if equipSkillGroupConfig == nil {
			return false
		}
		equipSkill.SkillGroup = equipSkillGroupConfig.Skill[0]
		equipSkill.Level = equipSkillGroupConfig.Skill[1]
		return true
	}
	logger.Error("no empty skill found")
	return false
}

// // EquipAffixAppend 装备词条追加
// func (u *User) EquipAffixAppend(equipAffixList *[EQUIP_AFFIX_LIST_MAX]EquipAffix, equipConfig *ConfigEquip, lockAffixIdList []int32) bool {
// 	logger.Debug("equip affix append, equipId: %v, uid: %v", equipConfig.Id, u.GetUid())
// 	equipAffixGroupListConfig := GetConfigEquipAffixGroupListByGroup(equipConfig.AffixGroup)
// 	if equipAffixGroupListConfig == nil {
// 		logger.Error("get equipAffixGroupConfig is nil, affixGroup: %v, uid: %v", equipConfig.AffixGroup, u.GetUid())
// 		return false
// 	}
// 	currAffixIdList := make([]int32, 0)
// 	for _, equipAffix := range equipAffixList {
// 		if equipAffix.AffixId == 0 {
// 			continue
// 		}
// 		currAffixIdList = append(currAffixIdList, equipAffix.AffixId)
// 	}
// 	affixGroupList := make([]*ConfigEquipAffixGroup, 0)
// 	if len(currAffixIdList) < int(equipConfig.MaxAffixNum) {
// 		// 解锁新的不重复词条
// 		for _, equipAffixGroupConfig := range equipAffixGroupListConfig {
// 			if slices.Contains[[]int32, int32](currAffixIdList, equipAffixGroupConfig.Affix) {
// 				continue
// 			}
// 			affixGroupList = append(affixGroupList, equipAffixGroupConfig)
// 		}
// 	} else {
// 		// 强化现有词条
// 		for _, currAffixId := range currAffixIdList {
// 			if slices.Contains[[]int32](lockAffixIdList, currAffixId) {
// 				continue
// 			}
// 			for _, equipAffixGroupConfig := range equipAffixGroupListConfig {
// 				if equipAffixGroupConfig.Affix == currAffixId {
// 					affixGroupList = append(affixGroupList, equipAffixGroupConfig)
// 				}
// 			}
// 		}
// 	}
// 	// 词条随机
// 	affixId := EquipAffixRandom(affixGroupList)
// 	if affixId == -1 {
// 		logger.Error("equip affix random error, uid: %v", u.GetUid())
// 		return false
// 	}
// 	// 寻找目标词条 新词条数组空位或既有词条对象
// 	var targetEquipAffix *EquipAffix = nil
// 	for i := 0; i < len(equipAffixList); i++ {
// 		equipAffix := &(equipAffixList[i])
// 		if equipAffix.AffixId == 0 || equipAffix.AffixId == affixId {
// 			targetEquipAffix = equipAffix
// 			break
// 		}
// 	}
// 	if targetEquipAffix == nil {
// 		logger.Error("can not found target equip affix, uid: %v", u.GetUid())
// 		return false
// 	}
// 	// 词条等级+1
// 	equipAffixConfig := GetConfigEquipAffixByAffixAndLevel(affixId, targetEquipAffix.Level+1)
// 	if equipAffixConfig == nil {
// 		logger.Error("get equipAffixConfig is nil, affix: %v, level: %v, uid: %v", affixId, targetEquipAffix.Level+1, u.GetUid())
// 		return false
// 	}
// 	// 词条战斗属性加成区间值随机
// 	propValue := EquipAffixPropValueRandom(equipAffixConfig)
// 	if propValue == -1 {
// 		logger.Error("equip affix prop add value random error, uid: %v", u.GetUid())
// 		return false
// 	}
// 	// 回写数据
// 	targetEquipAffix.AffixId = affixId
// 	targetEquipAffix.Level++
// 	targetEquipAffix.PropId = int32(equipAffixConfig.PropAddId)
// 	targetEquipAffix.PropAddType = int32(equipAffixConfig.PropAddType)
// 	targetEquipAffix.PropValue = propValue
// 	logger.Debug("equip affix append ok, equipAffixList: %v, uid: %v", equipAffixList, u.GetUid())
// 	return true
// }

// func EquipAffixRandom(equipAffixGroupListConfig []*ConfigEquipAffixGroup) int32 {
// 	weightAll := int32(0)
// 	for _, equipAffixGroupConfig := range equipAffixGroupListConfig {
// 		weightAll += equipAffixGroupConfig.Weight
// 	}
// 	randNum := tools.GetRandomInt32(0, weightAll-1)
// 	sumWeight := int32(0)
// 	for _, equipAffixGroupConfig := range equipAffixGroupListConfig {
// 		sumWeight += equipAffixGroupConfig.Weight
// 		if sumWeight > randNum {
// 			return equipAffixGroupConfig.Affix
// 		}
// 	}
// 	return -1
// }

// func EquipAffixPropValueRandom(equipAffixConfig *ConfigEquipAffix) int32 {
// 	weightAll := int32(0)
// 	for _, propAddRangeWeight := range equipAffixConfig.PropAddRangeWeight {
// 		if propAddRangeWeight.Left == 0 {
// 			break
// 		}
// 		weightAll += propAddRangeWeight.Weight
// 	}
// 	randNum := tools.GetRandomInt32(0, weightAll-1)
// 	sumWeight := int32(0)
// 	for _, propAddRangeWeight := range equipAffixConfig.PropAddRangeWeight {
// 		if propAddRangeWeight.Left == 0 {
// 			break
// 		}
// 		sumWeight += propAddRangeWeight.Weight
// 		if sumWeight > randNum {
// 			return tools.GetRandomInt32(propAddRangeWeight.Left, propAddRangeWeight.Right)
// 		}
// 	}
// 	return -1
// }

func (u *User) GetEquipSkillList(equipList []*Equip) []*gdconf.EquipSkillConfig {
	ret := make([]*gdconf.EquipSkillConfig, 0)
	if len(equipList) == 0 {
		return ret
	}
	skillGroupLevelMap := make(map[int32]int32)
	for _, equip := range equipList {
		equipConfig := gdconf.GetEquipConfig(equip.GetId())
		if equipConfig == nil {
			return ret
		}
		skillGroupLevelMap[equipConfig.ExSkill[0]] += equipConfig.ExSkill[1]
		for _, equipSkill := range equip.SkillList {
			if equipSkill.SkillGroup == 0 {
				break
			}
			skillGroupLevelMap[equipSkill.SkillGroup] += equipSkill.Level
		}
		for _, equipJewelKey := range equip.JewelList {
			if equipJewelKey == 0 {
				continue
			}
			equipJewel := u.GetEquipJewel4Key(equipJewelKey)
			if equipJewel == nil {
				logger.Error("equip jewel not exist, equipJewelKey: %v, uid: %v", equipJewelKey, u.GetUid())
				continue
			}
			equipJewelConfig := gdconf.GetEquipJewelConfig(equipJewel.GetId())
			if equipJewelConfig == nil {
				logger.Error("get equipJewelConfig is nil, jewelId: %v, uid: %v", equipJewel.GetId(), u.GetUid())
				continue
			}
			skillGroupLevelMap[equipJewelConfig.SkillGroup] += equipJewelConfig.SkillLevel
		}
	}
	for skillGroup, level := range skillGroupLevelMap {
		// 取配置表中的最大等级
		var equipSkillConfig *gdconf.EquipSkillConfig = nil
		for lv := level; lv > 0; lv-- {
			equipSkillConfig = gdconf.GetConfigEquipSkillByGroupAndLevel(skillGroup, lv)
			if equipSkillConfig != nil {
				break
			}
		}
		if equipSkillConfig == nil {
			logger.Error("can not find max level equip skill config, skillGroup: %v, level: %v, uid: %v", skillGroup, level, u.GetUid())
			continue
		}
		ret = append(ret, equipSkillConfig)
	}
	return ret
}

func (u *User) GetEquipRemainCellNum() int32 {
	return int32(USER_EQUIP - len(u.GetEquipMap()))
}

func PacketEquip(equip *Equip, user *User) *pb.Equip {
	// affixList := make([]*pb.EquipAffix, 0)
	// for _, equipAffix := range equip.AffixList {
	// 	if equipAffix.AffixId == 0 {
	// 		break
	// 	}
	// 	affixList = append(affixList, &pb.EquipAffix{
	// 		AffixId:     equipAffix.AffixId,
	// 		Level:       equipAffix.Level,
	// 		PropId:      equipAffix.PropId,
	// 		PropAddType: equipAffix.PropAddType,
	// 		PropValue:   equipAffix.PropValue,
	// 	})
	// }
	// affixRemakeList := make([]*pb.EquipAffix, 0)
	// for _, equipAffix := range equip.AffixRemakeList {
	// 	if equipAffix.AffixId == 0 {
	// 		break
	// 	}
	// 	affixRemakeList = append(affixRemakeList, &pb.EquipAffix{
	// 		AffixId:     equipAffix.AffixId,
	// 		Level:       equipAffix.Level,
	// 		PropId:      equipAffix.PropId,
	// 		PropAddType: equipAffix.PropAddType,
	// 		PropValue:   equipAffix.PropValue,
	// 	})
	// }
	jewelList := make([]*pb.EquipJewel, 0)
	for _, equipJewelKey := range equip.JewelList {
		if equipJewelKey == 0 {
			// 三个镶嵌孔都要发给客户端 空数据结构体代表没有
			jewelList = append(jewelList, new(pb.EquipJewel))
			continue
		}
		equipJewel := user.GetEquipJewel4Key(equipJewelKey)
		if equipJewel == nil {
			logger.Error("equip jewel not exist, equipJewelKey: %v, uid: %v", equipJewelKey, user.GetUid())
			continue
		}
		jewelList = append(jewelList, PacketEquipJewel(equipJewel))
	}
	equipSkillList := make([]*pb.EquipSkill, 0)
	for _, equipSkill := range equip.SkillList {
		if !equipSkill.IsUse() {
			continue
		}
		equipSkillList = append(equipSkillList, &pb.EquipSkill{
			SkillGroup: equipSkill.SkillGroup,
			Level:      equipSkill.Level,
		})
	}
	mainPropId, mainPropAddType, mainPropValue := equip.GetMainProp()
	return &pb.Equip{
		EquipKey:        BuildEquipKey(equip.GetId(), equip.Cell),
		ItemId:          equip.GetId(),
		Level:           int32(equip.Level),
		Exp:             equip.Exp,
		LevelGroup:      equip.LevelGroup,
		MainPropId:      mainPropId,
		MainPropAddType: int32(mainPropAddType),
		MainPropValue:   mainPropValue,
		// AffixList:       affixList,
		// AffixRemakeList: affixRemakeList,
		JewelList:      jewelList,
		RoleId:         equip.RoleId,
		EquipSkillList: equipSkillList,
	}
}

func (u *User) PacketUserEquipAll(rsp *pb.SC_Fetch) {
	equipList := make([]*pb.Equip, 0)
	equipJewelList := make([]*pb.EquipJewel, 0)
	for _, equip := range u.GetEquipMap() {
		equipList = append(equipList, PacketEquip(equip, u))
	}
	for _, equipJewel := range u.GetEquipJewelMap() {
		equipJewelList = append(equipJewelList, PacketEquipJewel(equipJewel))
	}
	rsp.Equip = &pb.UserEquip{
		EquipList:      equipList,
		EquipJewelList: equipJewelList,
	}
}
